#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/init.h>

static int irq;
static char* devname=NULL;
struct mydev
{
	int devid;
};
static struct mydev dev;

module_param(irq,int,0644);
module_param(devname,charp,0644);

struct tasklet_struct mytasklet;

static void mytasklet_handler(unsigned long data)
{
	printk("The tasklet is working...\n");
}

static irqreturn_t myirq_handler(int irq,void *dev)
{
	static int count=0;

	if(count<10)
	{
		printk("---------%d interrupt--------\n",count+1);
		printk("The interrupt handler is process the top half..\n");
		printk("The most of interrupt's work will be executived in the bottom half..\n");
		tasklet_init(&mytasklet,mytasklet_handler,0);
		tasklet_schedule(&mytasklet);
		printk("The ISR is leaving..\n");

	}
	count++;
	return IRQ_HANDLED;
}

static int __init mytasklet_init(void)
{
	printk("Module is working..\n");
	if(request_irq(irq,myirq_handler,IRQF_SHARED,devname,&dev)!=0)
	{
		printk("%s request IRQ:%d failed..\n",devname,irq);
		return -1;
	}
	printk("%s request IRQ:%d success..\n",devname,irq);
	return 0;
}

static void __exit mytasklet_exit(void)
{
	printk("Module is leaving..\n");
	free_irq(irq,&dev);
	printk("%s free IRQ:%d success..\n",devname,irq);
}

module_init(mytasklet_init);
module_exit(mytasklet_exit);
